package com.sjft.cloud.extension.generate;

import com.sjft.cloud.extension.generate.config.CustomFileGenerateConfig;
import com.sjft.cloud.extension.generate.fileout.UIApiFileOutConfig;
import com.sjft.cloud.extension.generate.fileout.UIRouteFileOutConfig;
import com.sjft.cloud.extension.generate.fileout.UIViewFileOutConfig;
import cn.hutool.core.lang.Assert;
import com.sjft.cloud.extension.generate.config.CustomGlobalConfig;
import com.sjft.cloud.extension.generate.config.CustomPackageConfig;
import com.sjft.cloud.extension.generate.properties.OutFileConfigProperties;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * GeneratorBuilder
 * 代码生产构造器
 *
 * @author Jin
 */
public class GeneratorBuilder {
   private final Generator generator = new Generator();

    private DataSourceConfig dataSourceConfig;

    private CustomPackageConfig packageConfig;

    private CustomGlobalConfig globalConfig;

    private StrategyConfig strategyConfig;

    private InjectionConfig injectionConfig;

    private AbstractTemplateEngine abstractTemplateEngine;

    public GeneratorBuilder setTemplateEngine(AbstractTemplateEngine abstractTemplateEngine) {
        this.abstractTemplateEngine = abstractTemplateEngine;
        return this;
    }

    public Generator getGenerator() {
        return generator;
    }

    /**
     * 包配置
     *
     * @param parent 包名
     * @param module 模块名
     * @return this
     */
    public GeneratorBuilder packageConfig(String parent, String module) {
        packageConfig = new CustomPackageConfig();
        packageConfig.setParent(parent);
        packageConfig.setModuleName(module);
        return this;
    }

    /**
     * 全局配置
     *
     * @param apiFileOutPutDir     接口文件输出目录
     * @param appFileOutPutDir     业务逻辑文件输出目录
     * @param openOutPutDir        是否打开文件输出目录
     * @param enableSwagger        是否启用swagger 注解
     * @param enableBaseResultMap  是否包含 BaseResultMap
     * @param enableBaseColumnList 是否包含 BaseColumnList
     * @param overrideFile         是否覆盖文件
     * @param dateType             日期类型
     * @param author               作者
     * @return this
     */
    public GeneratorBuilder globalConfig(String apiFileOutPutDir,
                                         String appFileOutPutDir,
                                         OutFileConfigProperties outFileConfigProperties,
                                         boolean openOutPutDir,
                                         boolean enableSwagger,
                                         boolean enableBaseResultMap,
                                         boolean enableBaseColumnList,
                                         boolean overrideFile,
                                         DateType dateType,
                                         String author) {
        globalConfig = new CustomGlobalConfig();
        globalConfig.setApiFileOutputDir(apiFileOutPutDir);
        globalConfig.setAppFileOutputDir(appFileOutPutDir);
        globalConfig.setOpen(openOutPutDir);
        globalConfig.setSwagger2(enableSwagger);
        globalConfig.setBaseResultMap(enableBaseResultMap);
        globalConfig.setBaseColumnList(enableBaseColumnList);
        globalConfig.setFileOverride(overrideFile);
        globalConfig.setDateType(dateType);
        globalConfig.setAuthor(author);
        globalConfig.setOutFileConfigProperties(outFileConfigProperties);
        return this;
    }

    /**
     * 数据源配置
     *
     * @return this
     */
    public GeneratorBuilder dataSourceConfig(String url, String driverName, String user, String password) {
        dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setDriverName(driverName);
        dataSourceConfig.setUrl(url);
        dataSourceConfig.setUsername(user);
        dataSourceConfig.setPassword(password);
        return this;
    }

    /**
     * 生成策略配置
     *
     * @return this
     */
    public GeneratorBuilder strategyConfig(String[] tablePrefix, String[] tableName, boolean entityLombokModel, boolean restControllerStyle) {
        strategyConfig = new StrategyConfig();
        strategyConfig.setNaming(NamingStrategy.underline_to_camel);
        strategyConfig.setSkipView(true);
        strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);
        strategyConfig.setEntityLombokModel(entityLombokModel);
        strategyConfig.setRestControllerStyle(restControllerStyle);
        strategyConfig.setTablePrefix(tablePrefix);
        strategyConfig.setInclude(tableName);
        strategyConfig.setSuperServiceImplClass(packageConfig.getParent() + StringPool.DOT + "common" + StringPool.DOT + "base" + StringPool.DOT + "service" + StringPool.DOT + "BaseService");
        return this;
    }


    /**
     * 自定义生成配置
     *
     * @return this
     */
    public GeneratorBuilder injectionConfig() {
        injectionConfig = new CustomFileGenerateConfig();
        List<FileOutConfig> fileOutList = new ArrayList<>();
        fileOutList.add(new UIApiFileOutConfig());
        fileOutList.add(new UIRouteFileOutConfig());
        fileOutList.add(new UIViewFileOutConfig());
        injectionConfig.setFileOutConfigList(fileOutList);
        injectionConfig.setMap(new HashMap<>());
        return this;
    }


    public static GeneratorBuilder build() {
        return new GeneratorBuilder();
    }

    public void execute() {
        Assert.notNull(packageConfig, "packageConfig 未配置");
        generator.setPackageInfo(packageConfig);
        Assert.notNull(dataSourceConfig, "dataSourceConfig 未配置");
        generator.setDataSource(dataSourceConfig);
        Assert.notNull(globalConfig, "globalConfig 未配置");
        generator.setGlobalConfig(globalConfig);
        Assert.notNull(strategyConfig, "strategyConfig 未配置");
        generator.setStrategy(strategyConfig);
        generator.setCfg(injectionConfig);
        generator.setTemplateEngine(abstractTemplateEngine);
        generator.execute();
    }

}
